//package com.swapper.hls;
//
//import com.swapper.base.CharUtils;
//import com.swapper.base.RuntimeSafe;
//import com.swapper.base.Scanner;
//
//import java.io.IOException;
//
//public final class HLSTokenizer {
//  private final Scanner scanner;
//
//  public HLSTokenizer(Scanner in) {
//    scanner = RuntimeSafe.nullSafe(in);
//  }
//
//  private String msg() throws IOException {
//    return CharUtils.unicode(scanner.previous()) + " "
//            + CharUtils.unicode(scanner.current()) + " "
//            + CharUtils.unicode(scanner.next());
//  }
//
//  public HLSToken tokenize() throws IOException {
//    char pre = scanner.current();
//    char ch = scanner.next();
//    if (pre == '\n' || pre == '\uffff') {
//      if (ch == '#') {
//        return readTagOrCommenting();
//      } else {
//        return readUri();
//      }
//    }
//    switch (ch) {
//      case ':':
//        return HLSToken.COLON;
//      case ',':
//        return HLSToken.COMMA;
//      case '=':
//        return HLSToken.EQUAL;
//      case '\r':
//        return HLSToken.RETURN;
//      case '\n':
//        return HLSToken.LINE_FEED;
//      case '\uffff':
//        return HLSToken.END;
//      case '"':
//        return readString();
//    }
//    if (ch >= '0' && ch <= '9') {
//      return readNumberOrDate();
//    }
//    if (ch >= 'A' && ch <= 'Z') {
//      return readEnumString();
//    }
//    throw new IllegalStateException(msg());
//  }
//
//  private HLSToken readUri() throws IOException {
//    StringBuilder builder = new StringBuilder();
//    builder.append(scanner.current());
//    while (true) {
//      char ch = scanner.next();
//      if (ch == '\r' || ch == '\n' || ch == '\uffff') {
//        scanner.rollback();
//        break;
//      }
//      builder.append(ch);
//    }
//    return new HLSToken(HLSToken.MASK_URI, builder.toString());
//  }
//
//  private HLSToken readString() throws IOException {
//    StringBuilder builder = new StringBuilder();
//    builder.append(scanner.current());
//    while (true) {
//      char ch = scanner.next();
//      if (ch == '\r' || ch == '\n' || ch == '\uffff') {
//        throw new IllegalStateException(msg());
//      }
//      if (ch == '"') {
//        break;
//      }
//      builder.append(ch);
//    }
//    return new HLSToken(HLSToken.MASK_STRING, builder.toString());
//  }
//
//  private HLSToken readTagOrCommenting() throws IOException {
//    StringBuilder builder = new StringBuilder();
//    builder.append(scanner.current());
//    char ch;
//    do {
//      ch = scanner.next();
//      if (ch == '\r' || ch == '\n' || ch == '\uffff') {
//        scanner.rollback();
//        return new HLSToken(HLSToken.MASK_COMMENTING, builder.toString());
//      }
//      builder.append(ch);
//    } while (builder.length() != 4);
//    if (builder.toString().equals("#EXT")) {
//      while (true) {
//        ch = scanner.next();
//        if (ch == '-' || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9')) {
//          builder.append(ch);
//        } else if (ch == ':' || ch == '\r' || ch == '\n' || ch == '\uffff') {
//          scanner.rollback();
//          return new HLSToken(HLSToken.MASK_TAG, builder.toString());
//        } else {
//          throw new IllegalStateException(msg());
//        }
//      }
//    } else {
//      while (true) {
//        ch = scanner.next();
//        if (ch == '\r' || ch == '\n' || ch == '\uffff') {
//          scanner.rollback();
//          return new HLSToken(HLSToken.MASK_COMMENTING, builder.toString());
//        }
//        builder.append(ch);
//      }
//    }
//  }
//
//  private HLSToken readNumberOrDate() throws IOException {
//    StringBuilder builder = new StringBuilder();
//    char first = scanner.current();
//    builder.append(first);
//    char ch = scanner.next();
//    if (first == '0' && (ch == 'x' || ch == 'X')) {
//      // read hex
//      builder.append(ch);
//      while (Scanner.isNotEnd(ch = scanner.next())) {
//        if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F')) {
//          builder.append(ch);
//        } else {
//          break;
//        }
//      }
//      if (ch == ',' || ch == '\r' || ch == '\n') {
//        scanner.rollback();
//        return new HLSToken(HLSToken.MASK_HEX_INTEGER, builder.toString());
//      } else {
//        throw new IllegalStateException(msg());
//      }
//    }
//    do {
//      if (ch >= '0' && ch <= '9') {
//        builder.append(ch);
//      } else {
//        break;
//      }
//    } while (Scanner.isNotEnd(ch = scanner.next()));
//    if (ch == '.') {
//      // read float
//      builder.append(ch);
//      while (Scanner.isNotEnd(ch = scanner.next())) {
//        if (ch >= '0' && ch <= '9') {
//          builder.append(ch);
//        } else {
//          break;
//        }
//      }
//      if (ch == ',' || ch == '\r' || ch == '\n') {
//        scanner.rollback();
//        return new HLSToken(HLSToken.MASK_FLOAT, builder.toString());
//      } else {
//        throw new IllegalStateException(msg());
//      }
//    }
//    // read dec
//    if (ch == ',' || ch == '\r' || ch == '\n') {
//      scanner.rollback();
//      return new HLSToken(HLSToken.MASK_DEC_INTEGER, builder.toString());
//    } else {
//      throw new IllegalStateException(msg());
//    }
//  }
//
//  private HLSToken readEnumString() throws IOException {
//    StringBuilder builder = new StringBuilder();
//    builder.append(scanner.current());
//    while (true) {
//      char ch = scanner.next();
//      if (ch == '-' || (ch >= 'A' && ch <= 'Z')) {
//        builder.append(ch);
//      } else if (ch == ',' || ch == '\r' || ch == '\n' || ch == '\uffff') {
//        scanner.rollback();
//        return new HLSToken(HLSToken.MASK_ENUM, builder.toString());
//      } else {
//        throw new IllegalStateException(msg());
//      }
//    }
//  }
//}
